/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.isd.facturacion.web;

import com.isd.facturacion.modelo.ItemProductoTienda;
import com.isd.facturacion.modelo.MovimientoTienda;
import com.isd.facturacion.rn.MovimientoFacturacionRN;
import com.isd.global.modelo.CorreoElectronico;
import com.isd.global.modelo.Parametro;
import com.isd.global.rn.MonedaRN;
import com.isd.global.rn.ParametrosRN;
import com.isd.global.util.JsfUtil;
import com.isd.global.util.SenderEmail;
import com.isd.global.web.MailFactory;
import com.isd.inventario.modelo.Producto;
import com.isd.inventario.vista.ItemCatalogo;
import com.isd.seguridad.web.UsuarioSessionBean;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.FlowEvent;


/**
 *
 * @author ctrosch
 */
@ManagedBean(name="carritoBean")
@SessionScoped
public class CarritoBean implements Serializable{

    @EJB private MovimientoFacturacionRN movimientoFacturacionRN;
    @EJB private ParametrosRN parametrosRN;
    @EJB private MonedaRN monedaRN;

    private MovimientoTienda carrito;    
    private List<MovimientoTienda> listaCarrito;

    //@Min(value=1, message="La cantidad debe ser mayor a cero" )
    private BigDecimal cantidadPedir;
    private BigDecimal bonificacion2;
    private int cantidadMaximaItem = 10;
    private boolean hayEquipos = false;    

    @ManagedProperty(value = "#{usuarioSessionBean}")
    private UsuarioSessionBean usuarioSession;

    @EJB private MailFactory mailFactoryBean;

    private Producto productoSeleccionado;

    private int viewStep;
    private ItemProductoTienda ItemProductoFacturacion;

    Parametro p;

    /** Creates a new instance of CarritoBean */
    public CarritoBean() {

    }

    @PostConstruct
    private void init(){
        try {

            p = parametrosRN.getParametros();

            cantidadMaximaItem = parametrosRN.getParametros().getCantidadMaximaItem();
            cantidadPedir = BigDecimal.ZERO;
            bonificacion2 = BigDecimal.ZERO;
            
            seleccionarCarritos();
        } catch (Exception ex) {
            cantidadMaximaItem = 0;
        }
    }

    public void guardarCarrito(){
        try {
            movimientoFacturacionRN.guardar(carrito);
            JsfUtil.addInfoMessage("Los datos han sido guardado exitosamente");
        } catch (Exception ex) {
            JsfUtil.addErrorMessage("No se puede guardar datos ");
        }
    }

    public void agregarProducto(ItemCatalogo ic){

        if(!puedoAgregarProducto(ic)) return;
        
        ItemProductoTienda item = movimientoFacturacionRN.nuevoItemProducto(carrito);
                
        try {
            item.setCantid(cantidadPedir);
            item.setProducto(ic.getProducto());

            BigDecimal cotizacion = monedaRN.getCotizacionDia(ic.getMoneda());
            //Precio de lista
            BigDecimal precio = ic.getPrecioLista().multiply(cotizacion);            
            
            item.setPrecio(precio);
            item.setPrenac(precio);
            item.setPresec(precio.divide(monedaRN.getCotizacionDia("USD"), 4 ,BigDecimal.ROUND_FLOOR));

            item.setPctbf1(ic.getBonificacion());
            item.setPctbf2(bonificacion2);
            item.setPctbfn(ic.getBonificacion().add(bonificacion2));

            //Precio final con bonificacion incluida
            BigDecimal precioFinal = precio.add(precio.multiply(item.getPctbfn()).divide(new BigDecimal(100)));

            item.setTotlin(cantidadPedir.multiply(precioFinal));

            item.setMonedaListaPrecio(carrito.getCoeficienteDeuda());
            item.setDeposito(carrito.getDeposito());
            item.setSector(carrito.getSector());
            item.setSucursal(carrito.getSucursal());
            item.setCliente(carrito.getCliente());
            item.setFchent(new Date());
            item.setFchhas(new Date());
            item.setUnimed(ic.getUnidadMedida());
            item.setUnifac(ic.getUnidadMedida());

            if(usuarioSession.getUsuario().getTipo().equals('V')){
                item.setOrigen("N");
            }else{
                item.setOrigen("W");
            }
            
            //item.setMovimiento(carrito);
            carrito.getItemsProducto().add(item);
            
            movimientoFacturacionRN.calcularImportesDocumento(carrito);
            movimientoFacturacionRN.guardar(carrito);

            JsfUtil.addInfoMessage("Se agregó "+cantidadPedir+ " "+ic.getUnidadMedida()+" del producto "+ ic.getProducto().getDescrp());
            cantidadPedir = BigDecimal.ZERO;
            bonificacion2 = BigDecimal.ZERO;
            ic.setSeleccionado(true);

        } catch (Exception e){
            carrito.getItemsProducto().remove(item);                        
            JsfUtil.addWarningMessage("No es posible agregar producto al carrito, disculpe las molestias");
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "agregarProducto", e);
        }
    }

    public boolean puedoAgregarProducto(ItemCatalogo ic){

        if (bonificacion2==null) bonificacion2 = BigDecimal.ZERO;

        boolean todoOk = true;
        String mensaje = "";

        if(carrito==null){
            JsfUtil.addErrorMessage("Seleccione un carrito");
            return false;
        }
        
        if(ic==null){
            JsfUtil.addErrorMessage("Nada para agregar");
            return false;
        }

        if(cantidadPedir.compareTo(BigDecimal.ZERO) <= 0){
            JsfUtil.addErrorMessage("Ingrese cantidad mayor o igual a 1");
            return false;
        }

        if(bonificacion2.compareTo(BigDecimal.ZERO) > 0 || bonificacion2.compareTo(new BigDecimal(-99.99)) <= 0 ){
            JsfUtil.addErrorMessage("La bonificación debe ser negativa, entre -99.99 y 0");
            return false;
        }
        
        if(carrito.getItemsProducto()!=null){
            for(ItemProductoTienda i: carrito.getItemsProducto()){
                if (i.getProducto().equals(ic.getProducto())){
                    JsfUtil.addErrorMessage("El producto "+ ic.getProducto().getDescrp() + " ya pertenece al carrito");
                    return false;
                }
            }
        }

        //Verificamos la cantidad maxima de items a pedir
        if(carrito.getCantidadItems() >= cantidadMaximaItem ){
            JsfUtil.addErrorMessage("No se puede agregar al carrito. Ha superado la cantidad máxima permitida para el carrito");
            return false;
        }

        if(ic.getPrecioFinal()==null){
            JsfUtil.addErrorMessage("Producto sin precio, no se puede agregar al carrito");
            return false;
        }

        if(ic.getPrecioFinal().compareTo(BigDecimal.ZERO)<=0){
            JsfUtil.addErrorMessage("Producto con precio igual o menor a cero, no se puede agregar al carrito");
            return false;
        }

        return todoOk;
    }

    public void eliminarProductoItemCatalogo(ItemCatalogo ic){

        eliminarProducto(ic.getProducto());
        ic.setSeleccionado(false);
    }
    
    public void eliminarProducto(Producto p){

        try {
            int i = 0;
            int indiceItem = -1;
            for(ItemProductoTienda ip: carrito.getItemsProducto()){

                if(ip.getProducto()!=null){

                    if(ip.getProducto().equals(p)){
                        indiceItem = i;
                    }
                }
                i++;
            }        
            if (indiceItem>=0){

                ItemProductoTienda remove = carrito.getItemsProducto().remove(indiceItem);
                movimientoFacturacionRN.calcularImportesDocumento(carrito);
                movimientoFacturacionRN.eliminarItem(remove);

                JsfUtil.addWarningMessage("El producto " + remove.getProducto().getDescrp() + " fue borrado del carrito");
            }else{
                JsfUtil.addErrorMessage("No se encontró producto a borrar");
            }

        } catch (Exception ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "eliminarProducto", ex);           
        }
    }

    public String seleccionarCarrito(MovimientoTienda m){
        
        try {
            movimientoFacturacionRN.recalcularValores(m, true);
            movimientoFacturacionRN.guardar(m);

            JsfUtil.addInfoMessage("Los precios están expresados en pesos y con I.V.A. incluido");
            JsfUtil.addInfoMessage("", "El importe total a facturar puede estar sujeto a percepciones");
            carrito = m;
            return "../facturacion/carritoDatos.xhtml";
        } catch (Exception e) {

            JsfUtil.addErrorMessage("Error al guardar datos " + e.getMessage());
            return "";
        }
    }

    public void seleccionarItemProducto(ItemProductoTienda i){

        ItemProductoFacturacion = i;
        
    }
    
    public boolean tengoVariosCarrito(){

        seleccionarCarritos();
        if(listaCarrito==null) return false;
        if(listaCarrito.isEmpty()) return false;
        if(listaCarrito.size()==1) return false;

        if(usuarioSession.getUsuario().getTipo().equals('V')){
            JsfUtil.addWarningMessage("El cliente posee varios carritos sin confirmar, seleccione el carrito con el cuál desea trabajar");
        }else{
            JsfUtil.addWarningMessage("Usted posee varios carritos sin confirmar, seleccione el carrito con el cuál desea trabajar");
        }

        JsfUtil.addInfoMessage("Puede agregar un nuevo carrito a su lista si lo cree necesario");
        return true;
    }

    public String nuevoCarrito(){

        if(usuarioSession.getUsuario().getTipo().equals('V')){
            generarCarritoVendedor();
        }else{
            generarCarritoCliente();
        }        
        
        JsfUtil.addInfoMessage("Ingrese una nota identificatoria si lo desea");
        return "/facturacion/carritoNuevo.xhtml";
    }

    public void modificarCantidad(){

        //Buscamos si el producto se encuentra en el detalle para modificarlo
        for(ItemProductoTienda i: carrito.getItemsProducto()){
            if (i.getProducto().equals(productoSeleccionado)){
                i.setCantid(cantidadPedir);
                i.setTotlin(i.getPrecio().multiply(cantidadPedir));
            }
        }
        cantidadPedir = BigDecimal.ONE;
        movimientoFacturacionRN.calcularImportesDocumento(carrito);
        guardarCarrito();
    }

    public String verConfirmarCarrito(){
        
        JsfUtil.addInfoMessage("Usted se encuentra en el proceso final para confirmar su carrito de compras, "
                    + "haga click en \"Paso siguiente \" hasta llegar al final de proceso. Muchas gracias");

        return "../ventas/confirmarCarrito.xhtml";
    }

    public String procesoConfirmacionCarrito(FlowEvent event){

        viewStep = 0;
        /**

        if(event.getNewStep().equals("facturacion")){

            viewStep = 1;
            JsfUtil.addInfoMessage("Modifique los datos de facturación si necesita que SIID S.R.L. emita "
                    + "la factura a otra Razon Social");
            JsfUtil.addInfoMessage("En caso de modificar que los datos de facturación, tenga en cuenta que debe enviar a siid"
                    + " mediante fax o correo electrónico, el formulario de inscripción a ingresos brutos para que podamos emitir la factura.");
            if(carrito.getDatosFactura()==null)
                carrito.setDatosFactura(new DatosFactura((Cliente)carrito.getCliente()));

            localidadesFactura = localidadRN.getLocalidadByProvincia(carrito.getDatosFactura().getProvincia());
        }

        if(event.getNewStep().equals("envio")){

            viewStep = 2;
            JsfUtil.addInfoMessage("Modifique los datos de envío si necesita que SIID S.R.L. envíe los productos "
                    + "solicitados a otra dirección diferente a la actual");
            if(carrito.getDatosEnvio()==null)
                carrito.setDatosEnvio(new DatosEnvio((Cliente)carrito.getCliente()));

            localidadesEnvio = localidadRN.getLocalidadByProvincia(carrito.getDatosEnvio().getProvincia());
        }

        if(event.getNewStep().equals("garantia")){

            viewStep = 3;
            for(ItemProductoFacturacion i: carrito.getDetalle()){
                if(i.getProducto().isEquipo()){

                    if(i.getDatosGarantia()==null)
                        i.setDatosGarantia(new DatosGarantiaEquipo((Cliente) carrito.getCliente(), i));

                    i.getDatosGarantia().setLocalidadesGarantia(localidadRN.getLocalidadByProvincia(i.getDatosGarantia().getProvincia()));
                }
            }

            JsfUtil.addInfoMessage("Ingrese los datos de garantía de los equipos configurados" );
            JsfUtil.addWarningMessage("La garantía comienza a correr a partir de los 45 "
                    + "días que fue despachado el equipo" );

        }

        if(event.getNewStep().equals("finalizacion")){

            JsfUtil.addInfoMessage("Todos los datos fueron validados. Haga click en \"Finalizar compra\" "
                    + "para que podamos procesar su carrito. Muchas gracias!");
        }
        */

        return event.getNewStep();
    }

    public void finalizarCompra(){

        try {
            carrito.setEstaut((short) 1 );
            carrito.setFchaut(new Date());
            carrito.setFchmov(JsfUtil.getFecha());

            if(carrito.getCliente().getValorUltimoScore()!=null){
                carrito.setValorUltimoScore(carrito.getCliente().getValorUltimoScore());
            }

            if(carrito.getCliente().getFechaUltimoScore()!=null){
                carrito.setFechaUltimoScore(carrito.getCliente().getFechaUltimoScore());
            }
            
            //Generamos items componentes si existen productos de tipo kit
            movimientoFacturacionRN.generoItemsComponente(carrito);
            movimientoFacturacionRN.guardar(carrito);
            enviarNotificaciones();
            carrito = null;
            
            JsfUtil.addInfoMessage("Muchas gracias. Su carrito de compras ha sido confirmado y será gestionado en breve");
            
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "finalizarCompra", e);
            JsfUtil.addErrorMessage("Error al confirmar carrito de compras");
        }

    }

    public String anularCarrito(){
        try {

            if(carrito==null){
                JsfUtil.addWarningMessage("No hay un carrito seleccionado para anular");
                return "";
            }

            carrito.setDebaja('S');
            movimientoFacturacionRN.guardar(carrito);            
            JsfUtil.addWarningMessage("El carrito ha sido anulado correctamente");
            seleccionarCarritos();
            carrito = null;

        }catch (Exception ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "anularCarrito", ex);    
            JsfUtil.addFatalMessage("No se puede anular carrito");
        }

        return verListaCarrito();
    }

    public void generarCarritoCliente(){

        try {
            carrito = movimientoFacturacionRN.nuevoMovimiento(usuarioSession.getUsuario().getCliente(), "FC", "PRW", "0110");
            movimientoFacturacionRN.guardar(carrito);

            if (carrito != null) {
                JsfUtil.addInfoMessage("Se ha creado un nuevo carrito");
            }
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "generarCarritoCliente", e);    
            JsfUtil.addErrorMessage("No se puede generar carrito");
        }
    }

    public void generarCarritoVendedor(){

        try {
            carrito = movimientoFacturacionRN.nuevoMovimiento(usuarioSession.getUsuario().getCliente(), "FC", "PRW", "0120");
            movimientoFacturacionRN.guardar(carrito);

            if (carrito != null) {
                JsfUtil.addInfoMessage("Se ha creado un nuevo carrito para el cliente");
            }
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "generarCarritoVendedor", e);    
            JsfUtil.addErrorMessage("No se puede generar carrito");
        }
    }

    public String verCarrito(){

        //Si está registrado buscamos el carrito de lo contrario vamos al catálogo
        if(!usuarioSession.isEstaRegistrado() || usuarioSession.getUsuario().getCliente()==null){

            if(usuarioSession.getUsuario().getTipo().equals('V')){
                JsfUtil.addWarningMessage("Seleccione un cliente para ver los carritos pendientes de confirmar");
            }

            return "";
        }
        
        try {
            if(carrito==null){

               if(tengoVariosCarrito()) return "../facturacion/carritoLista.xhtml";

               if(listaCarrito.size() == 1) {
                   carrito = listaCarrito.get(0);
                   JsfUtil.addInfoMessage("Se ha recuperado el último carrito sin confirmar");

               }else{
                    if(usuarioSession.getUsuario().getTipo().equals('V')){
                       generarCarritoVendedor();
                    }else{
                       generarCarritoCliente();
                    }
                }
            }

            JsfUtil.addInfoMessage("", "Los precios están expresados en pesos y con I.V.A. incluido");
            JsfUtil.addInfoMessage("", "El importe total a facturar puede estar sujeto a percepciones");
            return "../facturacion/carritoDatos.xhtml";
            
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "verCarrito", e);  
            JsfUtil.addErrorMessage("No es posible seleccionar su carrito guardado o generar uno nuevo");
            return "";
        }
    }

    public String verListaCarrito(){

        //Si está registrado buscamos el carrito de lo contrario vamos al catálogo
        if(usuarioSession.isEstaRegistrado() && usuarioSession.getUsuario().getCliente()!=null){

                seleccionarCarritos();
                if (listaCarrito.isEmpty()){
                    JsfUtil.addInfoMessage("No posee carritos pendientes de confirmar");
                }
                return "/facturacion/carritoLista.xhtml";
        
        }else{

            if(usuarioSession.getUsuario().getTipo().equals('V')){
                JsfUtil.addWarningMessage("Seleccione un cliente para ver los carritos pendientes de confirmar");
            }
            return "";
        }
    }

    public void actualizarCarrito(){
        try {
            movimientoFacturacionRN.recalcularValores(carrito,false);
            movimientoFacturacionRN.guardar(carrito);
            JsfUtil.addInfoMessage("Los datos han sido actualizados exitosamente");

        } catch (Exception ex) {
            JsfUtil.addErrorMessage("Error al actualizar datos del carrito actual","");
        }
    }

    public void seleccionarCarritos(){        
        
        if(usuarioSession.getUsuario().getCliente()==null) return;

        if(usuarioSession.getUsuario().getTipo().equals('V')){
            listaCarrito = movimientoFacturacionRN.getCarritoSinConfirmarVendedor(usuarioSession.getUsuario().getCliente());
        }else{
            listaCarrito = movimientoFacturacionRN.getCarritoSinConfirmarCliente(usuarioSession.getUsuario().getCliente());
        }       
    }   
   
    public void generarDocumentoPDF(Object document) throws IOException{
        try {
            document = movimientoFacturacionRN.generarPDF(carrito);
        } catch (Exception e) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "generarDocumentoPDF", e);              
        }
    }

    public void enviarNotificaciones(){

        try {

            if (p.getEnviaNotificaciones() == 'S') {

                List<CorreoElectronico> correos = new ArrayList<CorreoElectronico>();

                correos.add(generarCorreoElectronicoEmpresa());

                //Si es un usuario tipo cliente enviamos la notificación
                if(usuarioSession.getUsuario().getTipo().equals('C') || usuarioSession.getUsuario().getTipo().equals('P')){
                    correos.add(generarCorreoElectronicoCliente());
                }

                //Enviamos los correos con un nuevo hilo...
                SenderEmail se = new SenderEmail(mailFactoryBean, correos);
                se.start();
            }
        } catch (Exception e){
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "enviarNotificaciones", e);            
        }

    }

    public CorreoElectronico generarCorreoElectronicoCliente(){

        String  asunto = "Su carrito Nro. " + carrito.getId().getNrofor() + " ha sido confirmado";
        String destinatario = mailFactoryBean.validarDestinatario(carrito.getCliente().getDireml(), true);

        if(destinatario.isEmpty()) {
            destinatario = mailFactoryBean.validarDestinatario(carrito.getSitio().getEmailPedidos(),false);
            return new CorreoElectronico("Cliente sin e-mail", destinatario, JsfUtil.getMensajeClienteSinEmail(carrito.getCliente()));
        }

        String mensaje = mailFactoryBean.generarMensaje("Carrito confirmado",movimientoFacturacionRN.generarMensajeCorreoElectronico(carrito));
        return new CorreoElectronico(asunto, destinatario, mensaje);
    }

    public CorreoElectronico generarCorreoElectronicoEmpresa() {

        try {
            String asunto = "Presupuesto web Nro: "+ carrito.getId().getNrofor()+"- Cliente: " + carrito.getCliente().getNombre();
            String destinatario = mailFactoryBean.validarDestinatario(carrito.getSitio().getEmailPedidos(), false);

            if(usuarioSession.getUsuario().getTipo().equals('V')){
                asunto = carrito.getCliente().getVendedor().getDescrp() + " -  " + asunto;
                destinatario += (carrito.getVendedor().getCamail()==null?"":";"+carrito.getVendedor().getCamail());                
            }

            List<String> contenido = movimientoFacturacionRN.generarMensajeCorreoElectronico(carrito);
            
            contenido.set(0,"Nuevo presupuesto web");            
            contenido.set(1,"Detalle del pedido:");
            contenido.set(2,"<hr/>");
            contenido.set(3,"Cliente:" + carrito.getCliente().getNombre());
                       
            return new CorreoElectronico(asunto, destinatario, mailFactoryBean.generarMensaje("Carrito confirmado",contenido));

        } catch (Exception ex) {
            Logger.getLogger(getClass().getName()).log(Level.SEVERE, "generarCorreoElectronicoEmpresa", ex);           
            return new CorreoElectronico("Error", "claudiotrosch@gmail.com", "Problemas para generar correo confirmación de pedido a cliente" + ex.getStackTrace());
        }
    }


    //-------------------------------------------------------------------------

    public int getCantidadMaximaItem() {
        return cantidadMaximaItem;
    }

    public void setCantidadMaximaItem(int cantidadMaximaItem) {
        this.cantidadMaximaItem = cantidadMaximaItem;
    }

    public BigDecimal getCantidadPedir() {
        return cantidadPedir;
    }

    public void setCantidadPedir(BigDecimal cantidadPedir) {
        this.cantidadPedir = cantidadPedir;
    }

    public MovimientoTienda getCarrito() {
        return carrito;
    }

    public void setCarrito(MovimientoTienda carrito) {
        this.carrito = carrito;
    }

    public boolean isHayEquipos() {
        return hayEquipos;
    }

    public void setHayEquipos(boolean hayEquipos) {
        this.hayEquipos = hayEquipos;
    }

    public List<MovimientoTienda> getListaCarrito() {
        return listaCarrito;
    }

    public void setListaCarrito(List<MovimientoTienda> listaCarrito) {
        this.listaCarrito = listaCarrito;
    }

    public ItemProductoTienda getItemProductoFacturacion() {
        return ItemProductoFacturacion;
    }

    public void setItemProductoFacturacion(ItemProductoTienda ItemProductoFacturacion) {
        this.ItemProductoFacturacion = ItemProductoFacturacion;
    }

    public Producto getProductoSeleccionado() {
        return productoSeleccionado;
    }

    public void setProductoSeleccionado(Producto productoSeleccionado) {
        this.productoSeleccionado = productoSeleccionado;
    }

    public UsuarioSessionBean getUsuarioSession() {
        return usuarioSession;
    }

    public void setUsuarioSession(UsuarioSessionBean usuarioSession) {
        this.usuarioSession = usuarioSession;
    }

    public int getViewStep() {
        return viewStep;
    }

    public void setViewStep(int viewStep) {
        this.viewStep = viewStep;
    }

    public BigDecimal getBonificacion2() {
        return bonificacion2;
    }

    public void setBonificacion2(BigDecimal bonificacion2) {
        this.bonificacion2 = bonificacion2;
    }
    
    public Parametro getP() {
        return p;
    }

    public void setP(Parametro p) {
        this.p = p;
    }
    
}

